﻿using KeepAccounts.Models.Base;
using KeepAccounts.Models.PageModel;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace KeepAccounts.Repository.BaseRepository
{ 
      public interface IBaseRepository<TEntity> where TEntity : BaseEntity, new()
    {
        Task<TEntity> QueryById(object objId);
        Task<TEntity> QueryById(object objId, bool blnUseCache = false);
        Task<List<TEntity>> QueryByIds(object[] lstIds);

        Task<TEntity> GetEntity(Expression<Func<TEntity, bool>> whereExpression, string orderString = null);

        Task<int> Add(TEntity model);
        Task<int> Add(List<TEntity> models); 

        Task<bool> DeleteById(object id);

        Task<bool> Delete(TEntity model);

        Task<bool> DeleteByIds(object[] ids);
        /// <summary>
        /// 根据where条件删除数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        Task<bool> DeleteWhere(Expression<Func<TEntity, bool>> whereLambda);

        Task<bool> Update(TEntity model);
        Task<bool> Update(TEntity entity, string strWhere);

        Task<bool> Update(TEntity entity, List<string> lstColumns = null, List<string> lstIgnoreColumns = null, string strWhere = "");


        Task<bool> Update(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> expression);

        Task<List<TEntity>> Query();
        Task<List<TEntity>> Query(string strWhere);
        Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, bool IsDelete = false);
        Task<int> QueryCount(Expression<Func<TEntity, bool>> whereExpression);
        Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, string strOrderByFileds);

        Task<List<TResult>> Query<TResult>(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, TResult>> selectExpression, string strOrderByFileds);

        Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, Expression<Func<TEntity, object>> orderByExpression, bool isAsc = true);
        Task<List<TEntity>> Query(string strWhere, string strOrderByFileds);

        Task<List<TEntity>> Query(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds);

        Task<List<TResult>> QuerySelect<TResult>(Expression<Func<TEntity, bool>> whereExpression, int intTop, string strOrderByFileds, Expression<Func<TEntity, TResult>> selectExpression);




        Task<List<TEntity>> Query(string strWhere, int intTop, string strOrderByFileds);


        Task<List<TEntity>> Query(
            Expression<Func<TEntity, bool>> whereExpression, int intPageIndex, int intPageSize, string strOrderByFileds);
        Task<List<TEntity>> Query(string strWhere, int intPageIndex, int intPageSize, string strOrderByFileds);


        Task<PageResultModel<TEntity>> QueryPage(Expression<Func<TEntity, bool>> whereExpression, int pageIndex = 1, int pageSize = 20, string strOrderByFileds = null);

        Task<List<TResult>> QueryMuch<T, T2, T3, TResult>(
            Expression<Func<T, T2, T3, object[]>> joinExpression,
            Expression<Func<T, T2, T3, TResult>> selectExpression,
            Expression<Func<T, T2, T3, bool>> whereLambda = null, string orderString = null) where T : class, new();
        Task<List<TResult>> QueryMuch<T, T2, TResult>(
           Expression<Func<T, T2, object[]>> joinExpression,
           Expression<Func<T, T2, TResult>> selectExpression,
           Expression<Func<T, T2, bool>> whereLambda = null, string orderString = null) where T : class, new();


        Task<PageResultModel<TModel>> Pages<TModel>(BasePageQuery<TEntity> query);

        Task<PageResultModel<TModel>> PagesSelect<TModel>(BasePageQuery<TEntity> query, Expression<Func<TEntity, TModel>> selectExpression);

        Task<PageResultModel<TResult>> PagesMuch<T, T2, T3, T4, TResult>(
            BasePageQuery<TEntity> query,
           Expression<Func<T, T2, T3, T4, object[]>> joinExpression,
           Expression<Func<T, T2, T3, T4, TResult>> selectExpression,
           Expression<Func<T, T2, T3, T4, bool>> whereLambda = null) where T : class, new();
        
            Task<PageResultModel<TResult>> PagesMuch<T, T2, T3, TResult>(
            BasePageQuery<TEntity> query,
           Expression<Func<T, T2, T3, object[]>> joinExpression,
           Expression<Func<T, T2, T3, TResult>> selectExpression,
           Expression<Func<T, T2, T3, bool>> whereLambda = null) where T : class, new();

        Task<PageResultModel<TResult>> PagesMuch<T, T2, TResult>(
           BasePageQuery<TEntity> query,
          Expression<Func<T, T2, object[]>> joinExpression,
          Expression<Func<T, T2, TResult>> selectExpression,
          Expression<Func<T, T2, bool>> whereLambda = null) where T : class, new();


        Task<PageResultModel<TResult>> PagesMuchGroupBy<T, T2, TResult>(
  BasePageQuery<TEntity> query,
 Expression<Func<T, T2, object[]>> joinExpression,
  Expression<Func<T, T2, object>> groupByExpression,
 Expression<Func<T, T2, TResult>> selectExpression,
 Expression<Func<T, T2, bool>> whereLambda = null) where T : class, new();

        /// <summary>
        /// 不要使用多线程 会出错
        /// </summary>
        /// <returns></returns>
        Task<DbResult<bool>> UseTranAsync(Action action, Action<Exception> errorCallBack = null);
        /// <summary>
        /// 开启事务
        /// </summary>
        void BeginTran();
        /// <summary>
        /// 提交事务
        /// </summary>
        void CommitTran();
        /// <summary>
        /// 回滚事务
        /// </summary>
        void RollbackTran();

    }
}
